package game.games.map2d;

import game.AbstractGame;
import game.GraphicUtil;
import game.Position;
import game.games.paint.CellMap;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;

public class Map2D extends AbstractGame
{
    private static Map2D instance;
    
    public synchronized static Map2D getInstance()
    {
        if (instance == null)
        {
            synchronized (Map2D.class)
            {
                instance = new Map2D();
                // for (IConsoleCommand commandObj :
                // Map2DCommands.getCommands())
                // {
                // Console.getInstance().addConsoleCommand(commandObj);
                // }
            }
        }
        return instance;
    }

    private int mouseOverIndex = -1;
    
    private CellMap map;
    
    public Map2D()
    {
        super(true);
    }
    
    @Override
    public void render(Graphics gg)
    {
        if (map != null)
        {
            Position imgSize = new Position(map.getCellSize() * map.getSize().getWidth(), map.getCellSize() * map.getSize().getHeight());
            BufferedImage img = new BufferedImage(imgSize.getWidth(), imgSize.getHeight(), BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = img.createGraphics();
            GraphicUtil.fillRect(g, 0, 0, imgSize.getWidth(), imgSize.getHeight(), Color.WHITE);
            for (int index = 0; index < map.getSize().getSum(); index++)
            {
                Position position = map.calculatePosition(index);
                if (index == mouseOverIndex)
                {
                    map.fillRect(g, position.getX(), position.getY(), Color.RED);
                }
                else
                {
                    map.drawRect(g, position.getX(), position.getY(), Color.BLACK);
                }
                map.drawString(g, String.valueOf(index), ((map.getCellSize() / 10) * 6), position.getX(), position.getY(), Color.BLUE);
            }
            gg.drawImage(img, 0, 0, null);
            setSize(imgSize.getWidth(), imgSize.getHeight());
        }
    }

    @Override
    protected void doNext()
    {
    }
    
    @Override
    protected synchronized void start()
    {
        map = new CellMap(true, 50);
        super.start();
    }
    
    @Override
    protected synchronized void reset()
    {
        Position newSize = new Position(100,10);
        if (newSize.equals(map.getSize()) == false)
        {
            map.setSize(newSize);
        }
        super.reset();
    }
    
    @Override
    public KeyListener getKeyboardControl()
    {
        return new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e)
            {
                if (map != null)
                {
                    map.getKeyAdapter().keyPressed(e);
                }
            }
        };
    }
    
    @Override
    public MouseListener getMouseControl()
    {
        return new MouseAdapter() {};
    }
    
    @Override
    public MouseMotionListener getMouseMotionListener()
    { 
        return new MouseMotionAdapter() 
        {

            @Override
            public void mouseMoved(MouseEvent e)
            {
                if (isRunning())
                {
                    try
                    {
                        mouseOverIndex = map.calculateIndex(map.calcCoord(e.getPoint())); 
                    }
                    catch (IndexOutOfBoundsException ex)
                    {
                        mouseOverIndex = -1;
                    }
                }
            }
            
            @Override
            public void mouseDragged(MouseEvent e)
            {
                if (isRunning())
                {
                    try
                    {
                        mouseOverIndex = map.calculateIndex(map.calcCoord(e.getPoint())); 
                    }
                    catch (IndexOutOfBoundsException ex)
                    {
                        mouseOverIndex = -1;
                    }
                }
            }
        };
    }
    
    public static void main(String[] args)
    {
        Thread t = new Thread(Map2D.getInstance(), "Map2D");
        t.start();
    }
}
